import fs from 'fs/promises';
import path from 'node:path';
import { getDbConnection } from './db.js';

export class BackupManager {
  constructor() {
    this.backupDir = path.resolve(process.cwd(), './backups');
    this.ensureBackupDir();
  }

  async ensureBackupDir() {
    try {
      await fs.access(this.backupDir);
    } catch {
      await fs.mkdir(this.backupDir, { recursive: true });
    }
  }

  // 创建数据库备份
  async createBackup(type = 'manual') {
    try {
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const backupFilename = `knowledge_app_backup_${timestamp}.sqlite`;
      const backupPath = path.join(this.backupDir, backupFilename);
      
      // 获取数据库文件路径
      const db = await getDbConnection();
      const dbPath = db.config.filename;
      
      // 复制数据库文件
      await fs.copyFile(dbPath, backupPath);
      
      // 创建备份信息文件
      const backupInfo = {
        filename: backupFilename,
        type: type, // 'manual', 'auto', 'scheduled'
        created_at: new Date().toISOString(),
        size: (await fs.stat(backupPath)).size,
        original_path: dbPath
      };
      
      const infoPath = path.join(this.backupDir, `${backupFilename}.info.json`);
      await fs.writeFile(infoPath, JSON.stringify(backupInfo, null, 2));
      
      return {
        success: true,
        filename: backupFilename,
        path: backupPath,
        info: backupInfo
      };
    } catch (error) {
      console.error('创建备份失败:', error);
      throw error;
    }
  }

  // 获取备份列表
  async listBackups() {
    try {
      const files = await fs.readdir(this.backupDir);
      const backups = [];
      
      for (const file of files) {
        if (file.endsWith('.info.json')) {
          const infoPath = path.join(this.backupDir, file);
          const infoContent = await fs.readFile(infoPath, 'utf-8');
          const info = JSON.parse(infoContent);
          
          // 检查备份文件是否存在
          const backupPath = path.join(this.backupDir, info.filename);
          try {
            await fs.access(backupPath);
            backups.push(info);
          } catch {
            // 备份文件不存在，删除信息文件
            await fs.unlink(infoPath);
          }
        }
      }
      
      // 按创建时间倒序排列
      return backups.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
    } catch (error) {
      console.error('获取备份列表失败:', error);
      return [];
    }
  }

  // 删除备份
  async deleteBackup(filename) {
    try {
      const backupPath = path.join(this.backupDir, filename);
      const infoPath = path.join(this.backupDir, `${filename}.info.json`);
      
      // 删除备份文件
      await fs.unlink(backupPath);
      
      // 删除信息文件
      try {
        await fs.unlink(infoPath);
      } catch {
        // 信息文件可能不存在，忽略错误
      }
      
      return { success: true };
    } catch (error) {
      console.error('删除备份失败:', error);
      throw error;
    }
  }

  // 恢复备份
  async restoreBackup(filename) {
    try {
      const backupPath = path.join(this.backupDir, filename);
      const db = await getDbConnection();
      const dbPath = db.config.filename;
      
      // 验证备份文件存在
      await fs.access(backupPath);
      
      // 创建当前数据库的备份（以防恢复失败）
      const safetyBackup = await this.createBackup('before_restore');
      
      try {
        // 关闭当前数据库连接
        await db.close();
        
        // 复制备份文件到数据库位置
        await fs.copyFile(backupPath, dbPath);
        
        return { 
          success: true, 
          safetyBackup: safetyBackup.filename 
        };
      } catch (error) {
        // 恢复失败，尝试恢复安全备份
        try {
          await fs.copyFile(safetyBackup.path, dbPath);
        } catch (restoreError) {
          console.error('恢复安全备份也失败:', restoreError);
        }
        throw error;
      }
    } catch (error) {
      console.error('恢复备份失败:', error);
      throw error;
    }
  }

  // 清理旧备份（保留最新的N个）
  async cleanupBackups(keepCount = 10) {
    try {
      const backups = await this.listBackups();
      
      if (backups.length <= keepCount) {
        return { deletedCount: 0 };
      }
      
      const toDelete = backups.slice(keepCount);
      let deletedCount = 0;
      
      for (const backup of toDelete) {
        try {
          await this.deleteBackup(backup.filename);
          deletedCount++;
        } catch (error) {
          console.error(`删除备份失败 ${backup.filename}:`, error);
        }
      }
      
      return { deletedCount };
    } catch (error) {
      console.error('清理备份失败:', error);
      throw error;
    }
  }

  // 获取备份统计信息
  async getBackupStats() {
    try {
      const backups = await this.listBackups();
      const totalSize = backups.reduce((sum, backup) => sum + backup.size, 0);
      
      const typeStats = backups.reduce((stats, backup) => {
        stats[backup.type] = (stats[backup.type] || 0) + 1;
        return stats;
      }, {});
      
      return {
        totalBackups: backups.length,
        totalSize: totalSize,
        typeStats: typeStats,
        oldestBackup: backups[backups.length - 1]?.created_at || null,
        newestBackup: backups[0]?.created_at || null
      };
    } catch (error) {
      console.error('获取备份统计失败:', error);
      return {
        totalBackups: 0,
        totalSize: 0,
        typeStats: {},
        oldestBackup: null,
        newestBackup: null
      };
    }
  }
}
